export class StructureSocket {
  constructor (url) {
    this.ws = '' // 创建的ws对象，通过实例的ws来访问
    this.wssUri = url
    this.lockReconnect = false// 避免重复连接
    this.delayReconnect = null // 设置重连间隔
    this.receivedHandler = null // 收到消息的回调函数
    const _that = this
    // 心跳检测
    this.heartCheck = {
      timeout: 5000, // 每隔N秒发送心跳
      num: 3, // 3次心跳均未响应重连
      timeoutObj: null,
      serverTimeoutObj: null,
      start: function () {
        let _num = this.num
        this.timeoutObj && clearTimeout(this.timeoutObj)
        this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj)
        this.timeoutObj = setTimeout(() => {
          // 这里发送一个心跳，后端收到后，返回一个心跳消息，
          // onmessage拿到返回的心跳就说明连接正常
          if (_that.ws.readyState === 1) {
            _that.ws.send('ping') // 心跳包
            _num--
            // 计算答复的超时次数
            if (_num === 0) {
              _that.ws.close('1005', 'No Status Received')
            }
          } else {
            clearTimeout(this.timeoutObj)
          }
        }, this.timeout)
      }
    }
  }

  createWebSocket (receivedHandler) {
    try {
      this.ws = new WebSocket(this.wssUri)
      if (receivedHandler) {
        this.receivedHandler = receivedHandler
      }
      this.init()
    } catch (e) {
      console.log('catch')
      this.reconnect()
    }
  }

  init () {
    const _that = this
    this.ws.onclose = function (event) {
      console.log('链接关闭,原因是', event.reason)
      if (event.code !== 1000) {
        _that.reconnect()
      }
    }
    this.ws.onerror = function (err) {
      console.log('发生异常了')
      console.log(err)
      _that.reconnect()
    }
    this.ws.onopen = function () {
      // 心跳检测重置
      _that.heartCheck.start()
    }
    this.ws.onmessage = function (event) {
      let data = event.data
      if (isJsonString(event.data)) {
        data = JSON.parse(event.data)
      }
      // 拿到任何消息都说明当前连接是正常的
      _that.heartCheck.start()
      if (data !== 'pong') {
        // console.log(data)
        _that.receivedHandler(data) // 消息回调
      }
    }
  }

  reconnect () {
    const _that = this
    if (_that.lockReconnect) {
      return
    };
    _that.lockReconnect = true
    // 没连接上会一直重连，设置延迟避免请求过多
    _that.delayReconnect && clearTimeout(_that.delayReconnect)
    this.delayReconnect = setTimeout(function () {
      _that.createWebSocket()
      _that.lockReconnect = false
    }, 4000)
  }

  setSocketUrl (url) { // 用来重置socket地址
    this.wssUri = url
  }
}

function isJsonString (str) {
  try {
    if (typeof JSON.parse(str) === 'object') {
      return true
    }
  } catch (e) {
  }
  return false
}
